package com.bianguo.android.functiondemo.view.widget;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.os.Handler;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.AbsListView;
import android.widget.ListView;

import com.bianguo.android.functiondemo.R;

import java.lang.ref.WeakReference;

public class RickyListView extends ListView implements AbsListView.OnScrollListener {

    private View mScrollBarPanelView;
    private Animation inAnim, outAnim;
    private int mWidthMeasureSpec, mHeightMeasureSpec;
    private int mScrollBarPanelPosition;
    //定义指示器在ListView中的Y轴高度
    private int thumbOffset;
    private AnimHandler mHandler;
    private AnimRunnable mRunnable;

    private static class AnimHandler extends Handler {

        private final WeakReference<RickyListView> mReference;

        public AnimHandler(RickyListView view) {
            mReference = new WeakReference<>(view);
        }
    }

    private static class AnimRunnable implements Runnable {

        private final WeakReference<RickyListView> mReference;

        public AnimRunnable(RickyListView view) {
            mReference = new WeakReference<>(view);
        }

        @Override
        public void run() {
            RickyListView rickyListView = mReference.get();
            if (rickyListView.mScrollBarPanelView != null) {
                rickyListView.mScrollBarPanelView.startAnimation(rickyListView.outAnim);
            }
        }
    }

    public RickyListView(Context context) {
        super(context);
        initView(context, null);
    }

    public RickyListView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initView(context, attrs);
    }

    public RickyListView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initView(context, attrs);
    }

    private void initView(Context mContext, AttributeSet attrs) {
        super.setOnScrollListener(this);
        TypedArray typedArray = mContext.obtainStyledAttributes(attrs, R.styleable.RickyListView);
        final int layoutId = typedArray.getResourceId(R.styleable.RickyListView_scrollBarPanelView, R.layout.widget_ricky_scroll_bar_defalut_view);
        final int inAnimId = typedArray.getResourceId(R.styleable.RickyListView_scrollBarPanelViewInAnim, R.anim.mn_browser_enter_anim);
        final int outAnimId = typedArray.getResourceId(R.styleable.RickyListView_scrollBarPanelViewOutAnim, R.anim.mn_browser_exit_anim);
        typedArray.recycle();
        inAnim = AnimationUtils.loadAnimation(mContext, inAnimId);
        outAnim = AnimationUtils.loadAnimation(mContext, outAnimId);
        mScrollBarPanelView = LayoutInflater.from(mContext).inflate(layoutId, this, false);
        int duration = ViewConfiguration.getScrollBarFadeDuration();
        outAnim.setDuration(duration);
        outAnim.setAnimationListener(new Animation.AnimationListener() {
            @Override
            public void onAnimationStart(Animation animation) {

            }

            @Override
            public void onAnimationEnd(Animation animation) {
                if (mScrollBarPanelView != null) {
                    mScrollBarPanelView.setVisibility(GONE);
                }
            }

            @Override
            public void onAnimationRepeat(Animation animation) {

            }
        });
        mHandler = new AnimHandler(this);
        mRunnable = new AnimRunnable(this);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        this.mWidthMeasureSpec = widthMeasureSpec;
        this.mHeightMeasureSpec = heightMeasureSpec;
        if (mScrollBarPanelView != null && getAdapter() != null) {
            measureChild(mScrollBarPanelView, widthMeasureSpec, heightMeasureSpec);
        }
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        super.onLayout(changed, l, t, r, b);
        if (mScrollBarPanelView != null && getAdapter() != null) {
            int measuredWidth = mScrollBarPanelView.getMeasuredWidth();
            int left = getMeasuredWidth() - measuredWidth - getVerticalScrollbarWidth();
            mScrollBarPanelView.layout(left,
                    mScrollBarPanelPosition,
                    left + measuredWidth,
                    mScrollBarPanelPosition + mScrollBarPanelView.getMeasuredHeight());
        }
    }

    @Override
    protected void dispatchDraw(Canvas canvas) {
        super.dispatchDraw(canvas);
        if (mScrollBarPanelView != null && VISIBLE == mScrollBarPanelView.getVisibility()) {
            drawChild(canvas, mScrollBarPanelView, getDrawingTime());
        }
    }

    @Override
    protected boolean awakenScrollBars(int startDelay, boolean invalidate) {
        boolean awaken = super.awakenScrollBars(startDelay, invalidate);
        if (awaken && mScrollBarPanelView != null) {
            if (VISIBLE != mScrollBarPanelView.getVisibility()) {
                mScrollBarPanelView.setVisibility(VISIBLE);
                if (inAnim != null) {
                    mScrollBarPanelView.setAnimation(inAnim);
                }
            }
            mHandler.removeCallbacks(mRunnable);
            mHandler.postAtTime(mRunnable, startDelay + AnimationUtils.currentAnimationTimeMillis());
        }
        return awaken;
    }



    @Override
    public void onScrollStateChanged(AbsListView absListView, int i) {

    }

    @Override
    public void onScroll(AbsListView absListView, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
        if (mScrollBarPanelView != null) {
            //计算mScrollPanelPosition的值

//            computeVerticalScrollExtent();//滑块条在纵向滑动范围内经过放大后自身的高度
//            computeVerticalScrollOffset();//滑动条纵向幅度的位置
//            computeVerticalScrollRange();//滑动的范围:0~10000
            //1.滑块的高度，思路：滑块的高度 / ListView的高度 = Extent / range
            int height = Math.round(1.0f * getMeasuredHeight() * computeVerticalScrollExtent() / computeVerticalScrollRange());
            //2.得到系统滑块的中间Y坐标，思路：滑块的高度 / Extent = thumbOffset / Offset
            thumbOffset = height * computeVerticalScrollOffset() / computeVerticalScrollExtent();
            thumbOffset += height / 2;
            mScrollBarPanelPosition = thumbOffset - mScrollBarPanelView.getMeasuredHeight() / 2;

            //不断控制气泡View的摆放位置，invalidate方法效率不高
            int measuredWidth = mScrollBarPanelView.getMeasuredWidth();
            int left = getMeasuredWidth() - measuredWidth - getVerticalScrollbarWidth();
            mScrollBarPanelView.layout(left,
                    mScrollBarPanelPosition,
                    left + measuredWidth,
                    mScrollBarPanelPosition + mScrollBarPanelView.getMeasuredHeight());
        }
    }
}
